package com.ctyun.xstore.vod.template;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ctyun.xstore.vod.AbstractVODClient;
import com.ctyun.xstore.vod.ConcurrentPartUploader;
import com.ctyun.xstore.vod.template.model.CompleteWatermarkTemplateRequest;
import com.ctyun.xstore.vod.template.model.CompleteWatermarkTemplateResponse;
import com.ctyun.xstore.vod.template.model.CreateWatermarkTemplateRequest;
import com.ctyun.xstore.vod.template.model.CreateWatermarkTemplateResponse;
import com.ctyun.xstore.vod.template.model.DeleteWatermarkTemplateRequest;
import com.ctyun.xstore.vod.template.model.DeleteWatermarkTemplateResponse;
import com.ctyun.xstore.vod.template.model.GetWatermarkTemplateRequest;
import com.ctyun.xstore.vod.template.model.GetWatermarkTemplateResponse;
import com.ctyun.xstore.vod.template.model.SearchWatermarkTemplateRequest;
import com.ctyun.xstore.vod.template.model.SearchWatermarkTemplateResponse;

public final class WatermarkTemplateClient extends AbstractVODClient {

	private final Logger log = LoggerFactory.getLogger(WatermarkTemplateClient.class);

	private static final int CONVERT_UNIT = 1024 * 1024;

	private static final int WATERMARK_PICTURE_MAX_ALLOWED_SIZE = 5;

	private static final int PICTURE_TYPE_INFO_BYTE = 4;

	private static final int HEX_BIT_SHIFT = 4;

	public WatermarkTemplateClient(String accessKey, String secretKey) {
		super(accessKey, secretKey);
	}
	
	public WatermarkTemplateClient(String host, String accessKey, String secretKey) {
		super(host, accessKey, secretKey);
	}

	/**
	 * 创建水印模板
	 *
	 * @param request
	 *            创建转码模板请求CreateWatermarkTemplateRequest的实体类
	 * @return CreateWatermarkTemplateResponse, 创建水印模板返回类，仅包含templateId
	 * @throws IOException
	 *             可能抛出IO异常
	 */
	public CreateWatermarkTemplateResponse createWatermarkTemplate(CreateWatermarkTemplateRequest request)
			throws IOException {
		return this.execute(request, CreateWatermarkTemplateResponse.class);
	}

	/**
	 * 上传水印图片
	 *
	 * @param presignedUrl
	 *            水印图片上传的预签名url
	 * @param filePath
	 *            水印图片文件本地路径
	 * @return
	 * @throws java.net.MalformedURLException
	 *             presignedUrl不符合规范
	 * @throws Exception
	 *             其他异常
	 */
	public void uploadWatermarkPicture(String presignedUrl, String filePath) throws IOException {
		if (!isLegalPicture(filePath)) {
			throw new IllegalArgumentException("传入的水印图片不是PNG格式或者大小超过5M，请检查");
		}
		ConcurrentPartUploader s3UrlUploader = new ConcurrentPartUploader();
		s3UrlUploader.upload(presignedUrl, new File(filePath));
	}

	/**
	 * 完成水印图片上传
	 *
	 * @param templateId
	 *            指定水印模板的id
	 * @return CompleteWatermarkTemplateResponse, 完成水印图片上传的返回类，只包含code和message
	 * @throws IOException
	 *             可能抛出IO异常
	 */
	public CompleteWatermarkTemplateResponse completeWatermarkTemplate(String templateId) throws IOException {
		CompleteWatermarkTemplateRequest request = new CompleteWatermarkTemplateRequest(templateId);
		return this.execute(request, CompleteWatermarkTemplateResponse.class);
	}

	/**
	 * 搜索水印模板
	 *
	 * @param request
	 *            搜索水印模板请求SearchWatermarkTemplateRequest的实体类
	 * @return SearchWatermarkTemplateResponse,
	 *         搜索水印模板返回类，包含一个JSONArray，成员为WatermarkTemplate实体类
	 * @throws IOException
	 *             可能抛出IO异常
	 */
	public SearchWatermarkTemplateResponse searchWatermarkTemplate(SearchWatermarkTemplateRequest request)
			throws IOException {
		return this.execute(request, SearchWatermarkTemplateResponse.class);
	}

	/**
	 * 获取单个水印模板
	 *
	 * @param templateId
	 *            指定获取的水印模板的id
	 * @return GetWatermarkTemplateResponse, 获取单个水印模板返回类, 包含一个WatermarkTemplate
	 * @throws IOException
	 *             可能抛出IO异常
	 */
	public GetWatermarkTemplateResponse getWatermarkTemplate(String templateId) throws IOException {
		GetWatermarkTemplateRequest request = new GetWatermarkTemplateRequest(templateId);
		return this.execute(request, GetWatermarkTemplateResponse.class);
	}

	/**
	 * 删除水印模板
	 *
	 * @param templateId
	 *            指定删除的水印模板的id
	 * @return DeleteWatermarkTemplateResponse, 删除指定水印模板的返回类，只包含code和message
	 * @throws IOException
	 *             可能抛出IO异常
	 */
	public DeleteWatermarkTemplateResponse deleteWatermarkTemplate(String templateId) throws IOException {
		DeleteWatermarkTemplateRequest request = new DeleteWatermarkTemplateRequest(templateId);
		return this.execute(request, DeleteWatermarkTemplateResponse.class);
	}

	/**
	 * 判断水印图片是否为png格式，以及大小是否超过5M
	 *
	 * @param filePath
	 *            文件路径
	 * @return boolean 文件是否符合要求
	 */
	private boolean isLegalPicture(String filePath) {
		byte[] b = new byte[PICTURE_TYPE_INFO_BYTE];
		try (FileInputStream fis = new FileInputStream(filePath)) {
			fis.read(b, 0, b.length);
			String type = byteArrayToHexStr(b);
			if (!type.contains("89504E47")) {
				return false;
			}
			if ((fis.available() + PICTURE_TYPE_INFO_BYTE) / CONVERT_UNIT > WATERMARK_PICTURE_MAX_ALLOWED_SIZE) {
				return false;
			}
		} catch (IOException ex) {
			log.error("Assert watermark picture [{}] occurs error:", filePath, ex);
			return false;
		}
		return true;
	}

	/**
	 * byte数组转十六进制String的方法
	 *
	 * @param byteArray
	 * @return String
	 */
	private String byteArrayToHexStr(byte[] byteArray) {
		if (byteArray == null) {
			return null;
		}
		char[] hexArray = "0123456789ABCDEF".toCharArray();
		char[] hexChars = new char[byteArray.length * 2];
		for (int j = 0; j < byteArray.length; j++) {
			int v = byteArray[j] & 0xFF;
			hexChars[j * 2] = hexArray[v >>> HEX_BIT_SHIFT];
			hexChars[j * 2 + 1] = hexArray[v & 0x0F];
		}
		return new String(hexChars);
	}
}
